package com.runmonk.core.study.concurrent.volatile_test;


/**
 * @author  runmonk
 * @since  2019-09-10
 *
 * 测试volatile的可见性问题
 */
public class TestVolatile {
    /**
     * 主线程
     * @param args
     */
    public static void main(String[] args){

        ThreadDemo td=new ThreadDemo();
        new Thread(td).start();
        while (true){
            if (td.isFlag()){
                System.out.println("----------------------");
                break;
            }
        }
    }
}

/**
 * 内部类实现Runable接口
 */
class ThreadDemo implements  Runnable{
    private boolean flag = false;
    @Override
    public void run() {
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        flag=true;
        System.out.println("flag= "+flag);

    }
    public boolean isFlag(){
        return this.flag;
    }

}

/**
 * 当程序运行时，JVM为会每一个线程分配独立的缓存提高效率。共享数据flag=false当然是存在JVM内存中(确切的说，是随对象存储在堆里面)。
 * 线程将会将数据读取到自己缓存进行利用，更改后同步更新JVM内存中的数据。
 *
 * 由图可见，线程一new Thread(td)会去读取flag并进行修改然后再“反映”到JVM内存中的flag。那么为什么main里面的while循环一直拿不到更新后的true？
 *
 * 这里需要注意两点：
 *
 *   1、 new Thread(td)的run方法里面先Thread.sleep(200);让while (true)先执行了；
 *   2、  while (true){}调用了一系列的底层代码执行效率非常高，高到main没有机会获取内存中更新后的flag。
 *
 */
